/*
 * io.h
 *
 * Created: 8/22/2013 1:11:27 PM
 *  Author: Ken Arok
 * 
 * \brief Input Output Drivers
 *
 * Copyright (c) 2013 PT Hanindo Automation Solutions. All rights reserved.
 *
 */

/** \section section_io_driver I/O Drivers
 * \brief This module describes how to user API library of the I/O drivers.
 *
 * Example Usage.
 <pre>

 static send_command_and_get_repsonse(const void *_pbuf_write, void *_pbuf_read)
 {
   io_descriptor_t _com_desc;	//Declare I/O descriptor.

   _com_desc = vIO_Open("COM1", 0);	//Open COM1 port normally.
   if(_com_desc) {
   	   vIO_Ctrl(_com_desc, IORC_LOAD_SETTING_FROM_ROM, NULL);	//Parameter have to be loaded first before write and read.
   	   vIO_Write(_com_desc, _pbuf_write, 10, IORWF_BYTE_ORDER);	//Write 10 bytes data from Pointer _pbuf_write.
   	   vIO_Read(_com_desc, _pbuf_read, 10, IORWF_BYTE_ORDER);	//Read 50 bytes data and store to Pointer _pbuf_read.
   	   vIO_Close(_com_desc, 0);	//Close port
   }
 }

   </pre>
 */


#ifndef IO_H_
#define IO_H_

#include "FreeRTOS.h"


/*! \defgroup IO_DRIVERS I/O Drivers
 * \{
 *
 */

/** \name I/O Request Code.
 */
//! @{
#define IORC_RESTART_MODULE					0	//!< Restart module of I/O.
#define IORC_SET_DEFAULT					1	//!< Set I/O parameters to default.
#define IORC_LOAD_SETTING_FROM_ROM			2	//!< Load parameter setting of I/O from ROM.
#define IORC_SAVE_SETTING_TO_ROM			3	//!< Save parameter setting to ROM.
#define IORC_SET_RX_TIMEOUT					4	//!< Set receive timeout of I/O.
#define IORC_SET_SPEED						5	//!< Set transfer speed of I/O.
#define IORC_SET_DATA_BIT					6	//!< Set data width of I/O.
#define IORC_SET_MODE						7	//!< Set the I/O mode of SPI. Other interfaces are ignored.
#define IORC_SET_TRANSFER_POLLED_TX			8	//!< Set the transmitting of I/O is driven by Polled.
#define IORC_SET_TRANSFER_POLLED_RX			9	//!< Set the receiving of I/O is driven by Polled.
#define IORC_SET_TRANSFER_INTERRUPT_TX		10	//!< Set the transmitting of I/O is driven by Interrupt.
#define IORC_SET_TRANSFER_INTERRUPT_RX		11	//!< Set the receiving of I/O is driven by Interrupt.
#define IORC_SET_PARITY						12	//!< Set parity of UART I/O. Others are ignored.
#define IORC_SET_STOP_BIT					13	//!< Set stop bit of UART I/O. Others are ignored.
#define IORC_SET_DELAY_BS					14	//!< Set delay BS of SPI. Others are ignored.
#define IORC_SET_DELAY_BCT					15	//!< Set delay BCT of SPI. Others are ignored.
#define IORC_SET_KEEP_ACTIVE				16	//!< Set keep active of SPI. Others are ignored.
#define IORC_SET_SLAVE_ADDR					17	//!< Set slave address of I2C Device. Others are ignored.
#define IORC_TEST_SIGNAL					23	//!< Test a I/O interface if message/data has been already received.
#define IORC_RELEASE_SIGNAL					24	//!< Release I/O interface to be free.
#define IORC_GET_IO_SETTING					25	//!< Get Current I/O parameters setting.
//! @}

//! Data type of I/O request code.
typedef uint8_t	io_request_code_t;

/** \name I/O Read/Write Flag.
 */
//! @{
#define IORWF_BYTE_ORDER		1	//!< Byte order transfer (Data length 8 bit).
#define IORWF_WORD_ORDER		2	//!< Word order transfer (Data length 16 bit).
#define IORWF_DWORD_ORDER		3	//!, DWord order transfer (Data length 32 bit).
//! @}

//! Data type of I/O flag.
typedef uint8_t io_rw_flag_t;
//! Data type of I/O path name.
typedef const char * IO_path;
//! Data type of I/O descriptor.
typedef void * io_descriptor_t;

/** \name COM Port I/O parameter.
 */
//!@{
typedef struct
{
	uint32_t baudrate;			//!< Set baud rate of the UART.
	uint8_t charlength;			//!< Data width (5 to 9).
	uint8_t paritytype;			//!< Parity check.
	uint16_t stopbits;			//!< Stop bits (1 - 255). 0 means 1.5 stop bits.
} com_io_options_t;
//!@}

/** \brief Initilalize I/O Drivers.
 * <pre><io.h></pre>
 * <pre>\b portBASE_TYPE \b vIO_Init(void);</pre>
 */
void vIO_Init(void);

/** \brief Control I/O Behavior.
 * <pre>Goto \ref io_driver_example</pre>
 * <pre><io.h></pre>
 * <pre>\b portBASE_TYPE \b vIO_Ctrl(io_descriptor_t io_desc, io_request_code_t reqCode, void *pValue);</pre>
 *
 * @param io_desc		Pointer to I/O port descriptor.
 * @param reqCode		Request Code.
 * @param pValue		Pointer to the value. NULL if no value.
 * @return Status
 * @retval pdPASS = Success
 * @retval pdFAIL = Failed
 */
portBASE_TYPE vIO_Ctrl(io_descriptor_t io_desc, io_request_code_t reqCode, void *pValue);

/** \brief Open I/O Port.
 * <pre><io.h></pre>
 * <pre>\b portBASE_TYPE \b vIO_Open(IO_path path_name, uint8_t ioFlag);</pre>
 *
 * @param path_name		I/O path name.
 * @param ioFlag		Flag of opening.
 * <pre>0 = Normal opening.</pre>
 * <pre>1 = Open always.</pre>
 * <pre>2 = Force to open.</pre>
 * <pre>3 = Open without blocking.</pre>
 * @return	Pointer to I/O descriptor.
 */
io_descriptor_t vIO_Open(IO_path path_name, uint8_t ioFlag);

/** \brief Close I/O Port.
 * <pre><io.h></pre>
 * <pre>\b portBASE_TYPE \b vIO_Close(io_descriptor_t io_desc, const uint8_t ioFlag);</pre>
 *
 * @param io_desc	Pointer to I/O port descriptor.
 * @param ioFlag	Flag of closing.
 * <pre>0 = Normal closing.</pre>
 * <pre>1 = Ignored.</pre>
 * <pre>2 = Force to close.</pre>
 * <pre>3 = Close and ingnore blocking.</pre>
 * @return	Status
 * @retval pdPASS = Success
 * @retval pdFAIL = Failed
 */
portBASE_TYPE vIO_Close(io_descriptor_t io_desc, const uint8_t ioFlag);

/** \brief Write Data to I/O.
 * <pre><io.h></pre>
 * <pre>\b portBASE_TYPE \b vIO_Write(io_descriptor_t io_desc, const void *pBuf, uint32_t size, io_rw_flag_t flag);</pre>
 *
 * @param io_desc		Pointer to I/O port descriptor.
 * @param pBuf			Pointer to the buffer of data to be written.
 * @param size			Size of data to be written.
 * @param flag			Flag of writing operation.
 * <pre>IORWF_BYTE_ORDER = Byte order operation.</pre>
 * <pre>IORWF_WORD_ORDER = Word order operation.</pre>
 * <pre>IORWF_DWORD_ORDER = Double Word order operation.</pre>
 * @return	Status
 * @retval pdPASS = Success
 * @retval pdFAIL = Failed
 */
portBASE_TYPE vIO_Write(io_descriptor_t io_desc, const void *pBuf, uint32_t size, io_rw_flag_t flag);

/** \brief Read Data from I/O.
 * <pre><io.h></pre>
 * <pre>\b uint32_t \b vIO_Read(io_descriptor_t io_desc, void *pBuf, uint32_t size, io_rw_flag_t flag);</pre>
 *
 * @param io_desc		Pointer to I/O port descriptor.
 * @param pBuf			Pointer to the buffer where data will be stored.
 * @param size			Size of data to be read.
 * @param flag			Flag of writing operation.
 * <pre>IORWF_BYTE_ORDER = Byte order operation.</pre>
 * <pre>IORWF_WORD_ORDER = Word order operation.</pre>
 * <pre>IORWF_DWORD_ORDER = Double Word order operation.</pre>
 * @return	Status
 * @retval pdPASS = Success
 * @retval pdFAIL = Failed
 */
portBASE_TYPE vIO_Read(io_descriptor_t io_desc, void *pBuf, uint32_t size, io_rw_flag_t flag);

/**
 * \}
 */

#endif /* IO_H_ */
